package com.ccp.dev.qbdms.config;

import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;

/**
 * ClassDescribe:
 *
 * @author :milihao
 * @date :2020-8-17 Since:1
 */
@Configuration
@EnableAsync
public class ExecutorConfig {

	//todo 如果不想在代码里面写配置，可以将配置内容移到配置文件中
	/**
	 * 配置核心线程数
	 */
	private static final int CORE_POOL_SIZE = 4;
	/**
	 * 配置最大线程数
	 */
	private static final int MAX_POOL_SIZE = 200;
	/**
	 * 配置队列大小
	 */
	private static final int QUEUE_CAPACITY = 9999;

	@Bean
	public Executor reportAsync() {
		ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();
		executor.setCorePoolSize(CORE_POOL_SIZE);
		executor.setMaxPoolSize(MAX_POOL_SIZE);
		executor.setQueueCapacity(QUEUE_CAPACITY);
		executor.setThreadNamePrefix("reportAsync-");
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		executor.initialize();
		return executor;
	}
}
class VisiableThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
	private static final Logger LOGGER = LoggerFactory.getLogger(VisiableThreadPoolTaskExecutor.class);

	private void showThreadPoolInfo(String prefix){
		ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();

		LOGGER.info("{}, {},taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",
				this.getThreadNamePrefix(),
				prefix,
				threadPoolExecutor.getTaskCount(),
				threadPoolExecutor.getCompletedTaskCount(),
				threadPoolExecutor.getActiveCount(),
				threadPoolExecutor.getQueue().size());
	}

	@Override
	public void execute(Runnable task) {
		showThreadPoolInfo("do-execute-task");
		super.execute(task);
	}

	@Override
	public void execute(Runnable task, long startTimeout) {
		showThreadPoolInfo("do-execute-task");
		super.execute(task, startTimeout);
	}

	@Override
	public Future<?> submit(Runnable task) {
		showThreadPoolInfo("do-submit-task");
		return super.submit(task);
	}

	@Override
	public <T> Future<T> submit(Callable<T> task) {
		showThreadPoolInfo("do-submit-callableTask");
		return super.submit(task);
	}

	@Override
	public ListenableFuture<?> submitListenable(Runnable task) {
		showThreadPoolInfo("do-submitListenable-task");
		return super.submitListenable(task);
	}

	@Override
	public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
		showThreadPoolInfo("do-submitListenable-callableTask");
		return super.submitListenable(task);
	}

}
